home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Tools / HexEdit 1.0.7 ƒ / HexEditSource / Source / HexSearch.c < prev    next >
Text File  |  1994-09-25  |  7KB  |  323 lines

  1. /*********************************************************************
  2.  * HexSearch.c
  3.  *
  4.  * HexEdit, a simple hex editor
  5.  * copyright 1993, Jim Bumgardner
  6.  *********************************************************************/
  7. // Todo:
  8. //         Disable search buttons if text field is empty
  9.  
  10. #include "HexEdit.h"
  11.  
  12. #define SearchForwardItem    1
  13. #define SearchBackwardItem    2
  14. #define HexModeItem            3
  15. #define AsciiModeItem        4
  16. #define SearchTextItem        5
  17.  
  18. short            gSearchMode = EM_Ascii;
  19. short            gSearchDir = 0;    // 1 = backward
  20. unsigned char    gSearchBuffer[256],gSearchText[256],gGotoText[256];
  21. DialogPtr        gSearchWin;
  22. Boolean StringToSearchBuffer(void);
  23.  
  24.  
  25.  
  26.  
  27. void OpenSearchDialog(EditWindowPtr dWin)
  28. {
  29.     Str255    sStr;
  30.     // If Dialog Window isn't open
  31.     if (gSearchWin == NULL) {
  32.         // Open Dialog Window
  33.         MySetCursor(C_Arrow);
  34.         gSearchWin = GetNewDialog(SearchDLOG, NULL, (WindowPtr) -1L);
  35.         if (gSearchWin) {
  36.             // Convert Existing Search Scrap, if it exists to text
  37.             SetText(gSearchWin, SearchTextItem, gSearchText);
  38.  
  39.             // Set Radio Buttons
  40.             SetControl(gSearchWin, HexModeItem, gSearchMode == EM_Hex);
  41.             SetControl(gSearchWin, AsciiModeItem, gSearchMode == EM_Ascii);
  42.             SelIText(gSearchWin, SearchTextItem, 0, 32767);
  43.             ShowWindow(gSearchWin);
  44.         }
  45.     }
  46.     else
  47.         SelectWindow(gSearchWin);
  48. }
  49.  
  50. void PerformTextSearch(EditWindowPtr dWin)
  51. {
  52.     WindowPtr    wp;
  53.     short        ch,matchIdx;
  54.     long        addr,matchAddr;
  55.  
  56.     if (dWin == NULL) {
  57.         // Find and Select Top Window
  58.         wp = FrontWindow();
  59.         while (wp && ((WindowPeek) wp)->refCon != MyWindowID)
  60.             wp = (WindowPtr) ((WindowPeek) wp)->nextWindow;
  61.         if (wp == NULL || ((WindowPeek) wp)->refCon != MyWindowID)
  62.             return;
  63.         dWin = (EditWindowPtr) wp;
  64.     }
  65.  
  66.     MySetCursor(C_Watch);
  67.  
  68.     // Search in Direction gSearchDir
  69.     // for text gSearchBuffer
  70.  
  71.     if (gSearchDir == 0)
  72.         addr = dWin->endSel;
  73.     else {
  74.         addr = dWin->startSel - 1;
  75.         if (addr < 0)
  76.             return;
  77.     }
  78.     matchIdx = 0;
  79.     while (1) {
  80.         ch = GetByte(dWin, addr);
  81.         if (ch == gSearchBuffer[matchIdx+1]) {
  82.             if (matchIdx == 0)
  83.                 matchAddr = addr;
  84.             ++matchIdx;
  85.             if (matchIdx >= gSearchBuffer[0])
  86.                 goto Success;
  87.             ++addr;
  88.             if (addr == dWin->fileSize) {
  89.                 matchIdx = 0;
  90.                 addr = matchAddr;
  91.             }
  92.             else
  93.                 continue;
  94.         }
  95.         else {
  96.             if (matchIdx) {
  97.                 matchIdx = 0;
  98.                 addr = matchAddr;
  99.             }
  100.         }
  101.         if (gSearchDir == 0) {
  102.             ++addr;
  103.             if (addr == dWin->fileSize)
  104.                 goto Failure;
  105.         }
  106.         else {
  107.             --addr;
  108.             if (addr < 0)
  109.                 goto Failure;
  110.         }
  111.     }
  112.  
  113. Failure:
  114.     SysBeep(1);
  115.     MySetCursor(C_Arrow);
  116.     return;
  117.  
  118. Success:
  119.     if (dWin != (EditWindowPtr) FrontWindow())
  120.         SelectWindow((WindowPtr) dWin);
  121.     dWin->startSel = matchAddr;
  122.     dWin->endSel = dWin->startSel + gSearchBuffer[0];
  123.  
  124.     ScrollToSelection(dWin, dWin->startSel, true, true);
  125.     MySetCursor(C_Arrow);
  126. }
  127.  
  128.  
  129. #define GAddrItem            3
  130. #define GHexItem            4
  131. #define GAsciiItem            5
  132. #define GUserItem            6
  133.  
  134. pascal void GotoUserItem(DialogPtr dp, short itemNbr)
  135. {
  136.     switch (itemNbr) {
  137.     case GUserItem:
  138.         MyOutlineButton(dp, OK, black);
  139.         break;
  140.     }
  141.     
  142. }
  143.  
  144. void GotoAddress(EditWindowPtr dWin)
  145. {
  146.     GrafPtr        savePort;
  147.     DialogPtr    dp;
  148.     short        itemHit;
  149.     short        t;
  150.     Handle        h;
  151.     Rect        r;
  152.  
  153.     GetPort(&savePort);
  154.     MySetCursor(C_Arrow);
  155.     dp = GetNewDialog(GotoDLOG, NULL, (WindowPtr) -1L);
  156.     if (dp == NULL)
  157.         return;
  158.     GetDItem(dp, GUserItem, &t, &h, &r);
  159.     SetDItem(dp, GUserItem, t, (Handle) GotoUserItem, &r);
  160.  
  161.     SetText(dp, GAddrItem, gGotoText);
  162.     // Set Radio Buttons
  163.     SetControl(dp, GHexItem, gPrefs.decimalAddr == EM_Hex);
  164.     SetControl(dp, GAsciiItem, gPrefs.decimalAddr == EM_Ascii);
  165.     SelIText(dp, GAddrItem, 0, 32767);
  166.     ShowWindow(dp);
  167.     do {
  168.         ModalDialog(NULL, &itemHit);
  169.         switch (itemHit) {
  170.         case OK:
  171.             GetText(dp, GAddrItem, gGotoText);
  172.         case Cancel:
  173.             break;
  174.         case GHexItem:
  175.             gPrefs.decimalAddr = EM_Hex;
  176.             SetControl(dp, GHexItem, gPrefs.decimalAddr == EM_Hex);
  177.             SetControl(dp, GAsciiItem, gPrefs.decimalAddr == EM_Ascii);
  178.             break;
  179.         case GAsciiItem:
  180.             gPrefs.decimalAddr = EM_Ascii;
  181.             SetControl(dp, GHexItem, gPrefs.decimalAddr == EM_Hex);
  182.             SetControl(dp, GAsciiItem, gPrefs.decimalAddr == EM_Ascii);
  183.             break;
  184.         }
  185.     } while (itemHit != OK && itemHit != Cancel);
  186.     DisposDialog(dp);
  187.     SetPort(savePort);
  188.     if (itemHit == OK) {
  189.         long        addr = -1;
  190.         short        r;
  191.  
  192.         PtoCstr(gGotoText);
  193.         if (gPrefs.decimalAddr == EM_Hex)
  194.             r = sscanf((char *) gGotoText,"%lx",&addr);
  195.         else
  196.             r = sscanf((char *) gGotoText,"%ld",&addr);
  197.         CtoPstr((char *) gGotoText);
  198.         if (r == 1 && addr >= 0 && addr < dWin->fileSize) {
  199.             dWin->startSel = dWin->endSel = addr;
  200.             ScrollToSelection(dWin, addr, true, true);
  201.         }
  202.     }
  203. }
  204.  
  205.  
  206. void DoModelessDialogEvent(EventRecord *theEvent)
  207. {
  208.     DialogPtr    whichDlog;
  209.     short        itemHit;
  210.     // Do Event Filtering
  211.     if (theEvent->what == keyDown) {
  212.         // Process Edit Keys
  213.         if ((theEvent->message & charCodeMask) == '\r') {
  214.             whichDlog = FrontWindow();
  215.             itemHit = OK;
  216.             MySimulateButtonPress(whichDlog, OK);
  217.             goto ButtonHit;
  218.         }
  219.         if (theEvent->modifiers & cmdKey) {
  220.             switch ((theEvent->message & keyCodeMask) >> 8) {
  221.             case 0x0D:    // W
  222.                 DisposDialog(gSearchWin);
  223.                 gSearchWin = NULL;
  224.                 return;
  225.             case 0x0C:    // Q
  226.                 if (CloseAllEditWindows())
  227.                     gQuitFlag = true;
  228.                 return;
  229.             }
  230.         }
  231.     }
  232.     if(DialogSelect(theEvent, &whichDlog, &itemHit)) {
  233. ButtonHit:
  234.         if (whichDlog == gSearchWin) {
  235.             switch (itemHit) {
  236.             case SearchForwardItem:
  237.             case SearchBackwardItem:
  238.                 gSearchDir = (itemHit == SearchBackwardItem);
  239.                 GetText(gSearchWin, SearchTextItem, gSearchText);
  240.                 if (StringToSearchBuffer()) {
  241.                     PerformTextSearch(NULL);
  242.                 }
  243.                 break;
  244.             case HexModeItem:
  245.                 gSearchMode = EM_Hex;
  246.                 SetControl(gSearchWin, HexModeItem, gSearchMode == EM_Hex);
  247.                 SetControl(gSearchWin, AsciiModeItem, gSearchMode == EM_Ascii);
  248.                 break;
  249.             case AsciiModeItem:
  250.                 gSearchMode = EM_Ascii;
  251.                 SetControl(gSearchWin, HexModeItem, gSearchMode == EM_Hex);
  252.                 SetControl(gSearchWin, AsciiModeItem, gSearchMode == EM_Ascii);
  253.                 break;
  254.             case SearchTextItem:
  255.                 break;
  256.             }
  257.         }
  258.     }
  259.     else {
  260. /*        switch (theEvent->what) {*/
  261. /*        case updateEvt:*/
  262. /*            MyDoEvent(theEvent);*/
  263. /*            break;*/
  264. /*        }*/
  265.         if (theEvent->what == updateEvt && whichDlog == gSearchWin)
  266.             MyOutlineButton(gSearchWin, SearchForwardItem, black);
  267.     }
  268. }
  269.  
  270. Boolean StringToSearchBuffer(void)
  271. {
  272.     Ptr                sp, dp;
  273.     short            i;
  274.     short            val;
  275.     Boolean            loFlag;
  276.  
  277.     // Convert String to gSearchBuffer
  278.     if (gSearchMode == EM_Hex) {
  279.         sp = (Ptr) &gSearchText[1];
  280.         dp = (Ptr) &gSearchBuffer[1];
  281.         loFlag = false;
  282.         for (i = 0; i < gSearchText[0]; ++i,++sp) {
  283.             if (*sp == '0' && *(sp+1) == 'x') {
  284.                 loFlag = 0;
  285.                 ++sp;
  286.                 ++i;
  287.                 continue;
  288.             }
  289.             if (isspace(*sp) || ispunct(*sp)) {
  290.                 loFlag = 0;
  291.                 continue;
  292.             }
  293.             if (*sp >= '0' && *sp <= '9')
  294.                 val = *sp - '0';
  295.             else if (*sp >= 'A' && *sp <= 'F')
  296.                 val = 0x0A + (*sp - 'A');
  297.             else if (*sp >= 'a' && *sp <= 'f')
  298.                 val = 0x0A + (*sp - 'a');
  299.             else
  300.                 goto HexError;
  301.             if (loFlag) {
  302.                 *(dp-1) = (*(dp-1) << 4) | val;
  303.                 loFlag = 0;
  304.             }            
  305.             else {
  306.                 *dp = val;
  307.                 ++dp;
  308.                 loFlag = 1;
  309.             }
  310.         }
  311.         gSearchBuffer[0] = (long) dp - (long) &gSearchBuffer[1];
  312.         if (gSearchBuffer[0] == 0)
  313.             goto HexError;
  314.     }
  315.     else {
  316.         BlockMove(gSearchText, gSearchBuffer, gSearchText[0]+1);
  317.     }
  318.     return true;
  319. HexError:
  320.     ErrorAlert(ES_Caution, "Only valid Hex values may be used");
  321.     return false;
  322. }
  323.